﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace work1
{
    class runVisitor : Visitor
    {
        Dictionary<string, int> mapInt = new Dictionary<string, int>();
        Dictionary<string, string> mapString = new Dictionary<string, string>();
        Dictionary<string, bool> mapBool = new Dictionary<string, bool>();
        public int contains(string s)
        {
            if (mapInt.ContainsKey(s))
            {
                return 1;
            }
            else if (mapString.ContainsKey(s))
            {
                return 2;
            }
            else if (mapBool.ContainsKey(s))
            {
                return 3;
            }
            else return 0;
        }
        public char getOp(string res)
        {
            if (res.Contains('+'))
            {
                return '+';
            }
            if (res.Contains('-'))
            {
                return '-';
            }
            if (res.Contains('*'))
            {
                return '*';
            }
            if (res.Contains('/'))
            {
                return '/';
            }
            if (res.Contains('%'))
            {
                return '%';
            }
            else return '0';
        }
        public static bool IsNumeric(string value)
        {
            return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$");
        }
        public int getRes(int a,int b,char op)
        {
            if (op.Equals('+'))
            {
                return a+b;
            }
            if (op.Equals('-'))
            {
                return a-b;
            }
            if (op.Equals('*'))
            {
                return a*b;
            }
            if (op.Equals('/'))
            {
                return a/b;
            }
            if (op.Equals('%'))
            {
                return a % b;
            }
            return 0;
        }
        public String getBoolOp(string str)
        {
            if (str.Contains("<="))
            {
                return "<=";
            }
            else if (str.Contains("<"))
            {
                return "<";
            }
            else if (str.Contains(">="))
            {
                return ">=";
            }
            else if (str.Contains(">"))
            {
                return ">";
            }
            else if (str.Contains("=="))
            {
                return "==";
            }
            else if (str.Contains("!="))
            {
                return "!=";
            }
            else
            {
                return null;
            }
        }
        public bool getBoolRes(int a,int b,string op)
        {
            if (op.Equals("<"))
            {
                return a < b;
            }
            else if(op.Equals("<="))
            {
                return a <= b;
            }
            else if (op.Equals(">"))
            {
                return a > b;
            }
            else if (op.Equals(">="))
            {
                return a >= b;
            }
            else if (op.Equals("=="))
            {
                return a == b;
            }
            else if (op.Equals("!="))
            {
                return a != b;
            }
            return false;
        }
        public void delay()
        {
            double count = 5000;
            while (count > 0)
            {
                count -= 0.01;
                Console.Write(" ");
            }
        }
        Color color = Color.FromArgb(-986896);
        public void Visit(MyRectangle myRectangle, Graphics g)
        {
            myRectangle.LineList[0].StartGraohic.fill(g, color);
            myRectangle.fill(g,Color.LightGreen);
            string str = myRectangle.Letter;
            string[] data = str.Split(';');
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i].Contains("="))
                {
                    string[] operators = data[i].Split('=');
                    string l = operators[0];
                    int res = contains(l);
                    string r = operators[1];
                    //整形赋值
                    if (res == 1)
                    {
                        char op = getOp(r);
                        //普通赋值
                        if (op.Equals('0'))
                        {
                            int r2;
                            if (IsNumeric(r))
                            {
                                r2 = int.Parse(r);

                            }
                            else
                            {
                                r2 = mapInt[r];
                            }
                            mapInt[l] = r2;
                        }
                        //运算赋值
                        else
                        {
                            string[] right = r.Split(op);
                            string rl = right[0];
                            string rr = right[1];
                            int rll, rrr;
                            if (IsNumeric(rl))
                            {
                                if (IsNumeric(rr))
                                {
                                    rll = int.Parse(rl);
                                    rrr = int.Parse(rr);

                                }
                                else
                                {
                                    rll = int.Parse(rl);
                                    rrr = mapInt[rr];
                                }
                            }
                            else
                            {
                                if (IsNumeric(rr))
                                {
                                    rll = mapInt[rl];
                                    rrr = int.Parse(rr);

                                }
                                else
                                {
                                    rll = mapInt[rl];
                                    rrr = mapInt[rr];
                                }
                            }
                            mapInt[l] = getRes(rll, rrr, op);
                            Console.WriteLine(mapInt[l]);
                        }

                    }
                    //字符串赋值
                    else if (res == 2)
                    {
                        if (r.Contains("\""))
                        {
                            string temp1 = r.Substring(1);
                            string temp2 = temp1.Substring(0, r.Length - 2);
                            mapString[l] = temp2;
                            Console.WriteLine(mapString[l]);
                        }
                        else
                        {
                            mapString[l] = mapString[r];
                        }
                    }
                    //布尔赋值
                    else if (res == 3)
                    {
                        if (r.Contains("true"))
                        {
                            mapBool[l] = true;
                        }
                        else if (r.Contains("false"))
                        {
                            mapBool[l] = false;
                        }
                        else
                        {
                            mapBool[l] = mapBool[r];
                        }
                    }
                }
                else if(data[i].Contains("++"))
                {
                    string data1 = data[i].Substring(0, data[i].Length - 2);
                    Console.WriteLine(data1);
                    mapInt[data1] += 1;
                }
                else if (data[i].Contains("--"))
                {
                    string data1 = data[i].Substring(0, data[i].Length - 2);
                    Console.WriteLine(data1);
                    mapInt[data1] -= 1;
                }
            }
            if (myRectangle.LineList.Count>= 2)
            {
                delay();
                myRectangle.LineList[1].EndGrapthic.Accept(this, g);           
            }
        }
        public void Visit(Diamond diamond, Graphics g)
        {
            for(int i = 0; i < diamond.LineList.Count; i++)
            {
                if (diamond.isConnected(diamond.LineList[i].EndPoint)!=0)
                {
                    diamond.LineList[i].StartGraohic.fill(g, color);
                }
            }
            diamond.fill(g, Color.LightGreen);
            string str = diamond.Letter;
            string op = getBoolOp(str);
            //为布尔值
            if (op == null)
            {
                bool flag = mapBool[str];
                if (flag)
                {
                    for (int i = 0; i < diamond.LineList.Count; i++)
                    {
                        if (diamond.LineList[i].Letter != null)
                        {
                            if (diamond.LineList[i].Letter.Equals("Y"))
                            {
                                delay();
                                diamond.LineList[i].EndGrapthic.Accept(this, g);
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < diamond.LineList.Count; i++)
                    {
                        if (diamond.LineList[i].Letter != null)
                        {
                            if (diamond.LineList[i].Letter.Equals("N"))
                            {
                                delay();
                                diamond.LineList[i].EndGrapthic.Accept(this, g);
                            }
                        }
                    }
                }
            }
            //为布尔表达式
            else
            {
                string op1 = getBoolOp(str);
                bool flag;
                char[] ops = op1.ToCharArray();
                int index = str.IndexOf(ops[0]);
                string l = str.Substring(0, index);
                string r;
                if (ops.Length >= 2)
                {
                    r = str.Substring(index + 2);
                }
                else
                {
                    r = str.Substring(index + 1);
                }
                Console.WriteLine(r);
                int ll, rr;
                if (IsNumeric(l))
                {
                    ll = int.Parse(l);
                }
                else
                {
                    ll = mapInt[l];
                }
                if (IsNumeric(r))
                {
                    rr = int.Parse(r);
                }
                else
                {
                    rr = mapInt[r];
                }
                flag = getBoolRes(ll,rr , op1);
                if (flag)
                {
                    for (int i = 0; i < diamond.LineList.Count; i++)
                    {
                        if (diamond.LineList[i].Letter != null)
                        {
                            if (diamond.LineList[i].Letter.Equals("Y"))
                            {
                                delay();
                                diamond.LineList[i].EndGrapthic.Accept(this, g);
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < diamond.LineList.Count; i++)
                    {
                        if (diamond.LineList[i].Letter != null)
                        {
                            if (diamond.LineList[i].Letter.Equals("N"))
                            {
                                delay();
                                diamond.LineList[i].EndGrapthic.Accept(this, g);
                            }
                        }
                    }
                }
            }
        }

        public void Visit(Parallelogram parallelogram, Graphics g)
        {
            parallelogram.LineList[0].StartGraohic.fill(g, color);
            parallelogram.fill(g, Color.LightGreen);
            if (parallelogram.Letter.Contains("输入"))
            {
                string str = parallelogram.Letter;
                string subStr = str.Substring(2);
                string[] data = subStr.Split(',');
                for (int i = 0; i < data.Length; i++)
                {
                    if (data[i].Contains("整形"))
                    {
                        string name = data[i].Substring(2);
                        mapInt.Add(name, 0);
                    }
                    if (data[i].Contains("布尔"))
                    {
                        string name = data[i].Substring(2);
                        mapBool.Add(name, false);
                    }
                    if (data[i].Contains("字符串"))
                    {
                        string name = data[i].Substring(3);
                        mapString.Add(name, null);
                    }
                }
            }
            if (parallelogram.Letter.Contains("输出"))
            {
                string str = parallelogram.Letter;
                string subStr = str.Substring(2);
                Console.WriteLine(mapInt[subStr]);
            }
            if (parallelogram.LineList.Count >=2)
            {
                delay();
                parallelogram.LineList[1].EndGrapthic.Accept(this, g);              
            }
        }

        public void Visit(Ellipse ellipse, Graphics g)
        {
            ellipse.fill(g, Color.LightGreen);
            String str = ellipse.Letter;
            if (str.Equals("开始"))
            {
                if (ellipse.LineList.Count > 0)
                {
                    delay();
                    ellipse.LineList[0].EndGrapthic.Accept(this, g);
                }
            }
            else
            {
                ellipse.LineList[0].StartGraohic.fill(g, color);
                delay();
                ellipse.fill(g, color);
            }
        }

        public void Visit(Circle circle, Graphics g)
        {
            for (int i = 0; i < circle.LineList.Count; i++)
            {
                if (circle.isConnected(circle.LineList[i].EndPoint) != 0)
                {
                    circle.LineList[i].StartGraohic.fill(g, color);
                }
            }
            circle.fill(g,Color.LightGreen);
            if (circle.LineList.Count >= 3)
            {
                delay();
                circle.LineList[2].EndGrapthic.Accept(this, g);
            }
        }
    }
}
